﻿using System;
using System.Collections.Generic;
using System.Linq;
using Unis.Framework.Core.Exceptions;
using Unis.Framework.Core.Utility;
using Unis.Framework.ORM.Mapping;
using Unis.ORM.Mapping;

namespace Unis.Framework.ORM.Persistence
{
    public sealed class EntityIdentityHelper
    {
        // Fields
        private static readonly string PARAM_CURRENT_VALUE = "CurrentValue";
        private static readonly string PARAM_IDENTITY_INCREMENT = "IdentityIncrement";
        private static readonly string PARAM_IDENTITY_SEED = "IdentitySeed";
        private static readonly string PARAM_TABLE_NAME = "TableName";
        private static readonly string SYS_IDENTITY_TABLE_NAME = "SYS_OBJECT_IDENTITY";

        // Methods
        //private int createEntityIdentity(Database db, string tableName, int count)
        //{
        //    int num = 1;
        //    using (DbConnection connection = db.CreateConnection())
        //    {
        //        connection.Open();
        //        DbTransaction transaction = connection.BeginTransaction();
        //        try
        //        {
        //            try
        //            {
        //                string newValue = (DatabaseConfigurationScope.GetDatabaseType(db) == DatabaseType.Oracle) ? SqlShareHelper.ORACLE_PARAM_PREFIX : SqlShareHelper.SQL_SERVER_PARAM_PREFIX;
        //                string query = "SELECT CURRENT_VALUE FROM SYS_OBJECT_IDENTITY WHERE TABLE_NAME=:TableName".Replace(":", newValue);
        //                DbCommand sqlStringCommand = db.GetSqlStringCommand(query);
        //                db.AddInParameter(sqlStringCommand, newValue + PARAM_TABLE_NAME, DbType.String, tableName);
        //                TraceEx.Write("正在执行GetEntityIdentity 中的 Select:" + DbCommandExecuteTrack.Instance.CommandToTrackMessage(db, sqlStringCommand));
        //                object orgData = db.ExecuteScalar(sqlStringCommand, transaction);
        //                sqlStringCommand.Dispose();
        //                if ((orgData == null) || (orgData == DBNull.Value))
        //                {
        //                    string str3 = "INSERT INTO SYS_OBJECT_IDENTITY(TABLE_NAME,CURRENT_VALUE) VALUES(:TableName,:CurrentValue)".Replace(":", newValue);
        //                    DbCommand command = db.GetSqlStringCommand(str3);
        //                    db.AddInParameter(command, newValue + PARAM_TABLE_NAME, DbType.String, tableName);
        //                    db.AddInParameter(command, newValue + PARAM_CURRENT_VALUE, DbType.String, (num + count) - 1);
        //                    TraceEx.Write("正在执行GetEntityIdentity 中的 Insert:" + DbCommandExecuteTrack.Instance.CommandToTrackMessage(db, sqlStringCommand));
        //                    db.ExecuteNonQuery(command, transaction);
        //                    command.Dispose();
        //                }
        //                else
        //                {
        //                    num = MyConvert.Instance.ToInt(orgData) + 1;
        //                    string str4 = "UPDATE SYS_OBJECT_IDENTITY SET CURRENT_VALUE=:CurrentValue WHERE TABLE_NAME=:TableName".Replace(":", newValue);
        //                    DbCommand command3 = db.GetSqlStringCommand(str4);
        //                    db.AddInParameter(command3, newValue + PARAM_TABLE_NAME, DbType.String, tableName);
        //                    db.AddInParameter(command3, newValue + PARAM_CURRENT_VALUE, DbType.String, (num + count) - 1);
        //                    TraceEx.Write("正在执行GetEntityIdentity 总的 Update:" + DbCommandExecuteTrack.Instance.CommandToTrackMessage(db, sqlStringCommand));
        //                    db.ExecuteNonQuery(command3, transaction);
        //                    command3.Dispose();
        //                }
        //                transaction.Commit();
        //            }
        //            catch (Exception exception)
        //            {
        //                transaction.Rollback();
        //                throw new APPException("执行 GetEntityIdentity 出错！", APPMessageType.SysDatabaseInfo, exception);
        //            }
        //            return num;
        //        }
        //        finally
        //        {
        //            try
        //            {
        //                transaction.Dispose();
        //                if (connection.State == ConnectionState.Open)
        //                {
        //                    connection.Close();
        //                }
        //            }
        //            catch
        //            {
        //            }
        //        }
        //    }
        //    return num;
        //}

        //public void FillEntityIdentity(object entity)
        //{
        //    Type t = entity.GetType();
        //    ModelMappingInfo modelMappingInfo = AttMappingManager.Instance.GetModelMappingInfo(t);
        //    if (string.IsNullOrEmpty(modelMappingInfo.MapTable))
        //    {
        //        throw new APPException(string.Format("数据实体{0} 配置有误，没有指定映射到的表。", t.FullName), APPMessageType.SysErrInfo);
        //    }
        //    if ((modelMappingInfo.PrimaryKeys == null) || (modelMappingInfo.PrimaryKeys.Count != 1))
        //    {
        //        throw new APPException(string.Format("数据实体{0} 配置有误，没有指定主键或者不是单一主键配置。", t.FullName), APPMessageType.SysErrInfo);
        //    }
        //    FieldPropertyInfo info2 = modelMappingInfo.PrimaryKeys.Values.First<FieldPropertyInfo>();
        //    if (MyReflection.Instance.CheckObjectExistsProperty(entity, info2.FieldName))
        //    {
        //        object obj2 = MyReflection.Instance.InvokePropertyForGet(entity, info2.FieldName);
        //        if ((obj2 == null) || (((int)obj2) <= 0))
        //        {
        //            int entityIdentity = this.GetEntityIdentity(modelMappingInfo.MapTable);
        //            MyReflection.Instance.InvokePropertyForSet(entity, info2.FieldName, entityIdentity);
        //        }
        //    }
        //}

        //public int GetEntityIdentity(string tableName)
        //{
        //    return this.GetEntityIdentity(tableName, 1);
        //}

        //public int GetEntityIdentity(string tableName, int count)
        //{
        //    int num;
        //    Database db = DatabaseHelper.CreateDatabase();
        //    switch (DatabaseConfigurationScope.GetDatabaseType(db))
        //    {
        //        case DatabaseType.MSSQLServer:
        //        case DatabaseType.Sqlite:
        //        case DatabaseType.MySql:
        //            return this.createEntityIdentity(db, tableName, count);
        //    }
        //    string query = "SELECT FU_GET_NEXT_IDENTITY(:pTABLE_NAME,:pCOUNT) FROM DUAL";
        //    DbCommand sqlStringCommand = db.GetSqlStringCommand(query);
        //    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.RequiresNew))
        //    {
        //        try
        //        {
        //            db.AddInParameter(sqlStringCommand, "pTABLE_NAME", DbType.AnsiString, tableName);
        //            db.AddInParameter(sqlStringCommand, "pCOUNT", DbType.Int32, count);
        //            object orgData = db.ExecuteScalar(sqlStringCommand);
        //            scope.Complete();
        //            num = MyConvert.Instance.ToInt(orgData);
        //        }
        //        catch (Exception exception)
        //        {
        //            throw new APPException("执行 GetEntityIdentity 出错！", APPMessageType.SysDatabaseInfo, exception);
        //        }
        //        finally
        //        {
        //            try
        //            {
        //                sqlStringCommand.Dispose();
        //            }
        //            catch
        //            {
        //            }
        //        }
        //    }
        //    return num;
        //}

        private List<string> createEntityIdentity(int count)
        {
            List<string> list = new List<string>();
            for (int i = 0; i < count; i++)
            {
                list.Add(Guid.NewGuid().ToString().ToUpper());
            }
            return list;
        }

        public string GetEntityIdentity()
        {
            return this.GetEntityIdentity(1).First();
        }

        public List<string> GetEntityIdentity(int count)
        {
            return createEntityIdentity(count);
        }

        public void FillEntityIdentity(object entity)
        {
            Type t = entity.GetType();
            ModelMappingInfo modelMappingInfo = AttMappingManager.Instance.GetModelMappingInfo(t);
            if (string.IsNullOrEmpty(modelMappingInfo.MapTable))
            {
                throw new APPException(string.Format("数据实体{0} 配置有误，没有指定映射到的表。", t.FullName), APPMessageType.SysErrInfo);
            }
            if ((modelMappingInfo.PrimaryKeys == null) || (modelMappingInfo.PrimaryKeys.Count != 1))
            {
                throw new APPException(string.Format("数据实体{0} 配置有误，没有指定主键或者不是单一主键配置。", t.FullName), APPMessageType.SysErrInfo);
            }
            FieldPropertyInfo info2 = modelMappingInfo.PrimaryKeys.Values.First<FieldPropertyInfo>();
            if (Reflection.CheckObjectExistsProperty(entity, info2.FieldName))
            {
                object obj2 = Reflection.GetObjectProperty(entity, info2.FieldName);
                //if ((obj2 == null) || (((int)obj2) <= 0))
                if (obj2 == null || String.IsNullOrEmpty(Convert.ToString(obj2).Trim()))
                {
                    string entityIdentity = this.GetEntityIdentity();
                    Reflection.SetObjectProperty(entity, info2.FieldName, entityIdentity);
                }
            }
        }

        // Properties
        public static EntityIdentityHelper NewInstance
        {
            get
            {
                return new EntityIdentityHelper();
            }
        }
    }
}
